import { ClassUtil } from "../../ClassUtil";
import { WebGLUtil } from "../../utils/WebGLUtil";
import { Render } from "../Render";
import { ToolUI } from "../ToolUI";

/*
 * @Author: Snow
 * @Date: 2021-10-11 10:25:40
 * @Description: 模板基类
 */
export class WebglTemplateBase extends ToolUI {
    protected ts:number;
    public vsSource: string;

    public fsSource: string;

    public shaderProgram: WebGLProgram;

    public programInfo:{
		program: WebGLProgram,
		uniformSetters: { [name: string]: Function },
		attribSetters: { [name: string]: Function },
	};

    constructor() {
        //ClassUtil.reg()
        super();
        this.initUITools();
        this.initProgram();
        this.initBuffers();
    }

    protected initProgram(): void {
        // this.vsSource = `
        //     uniform mat4 u_worldViewProjection;
        //     uniform vec3 u_lightWorldPos;
        //     uniform mat4 u_world;
        //     uniform mat4 u_viewInverse;
        //     uniform mat4 u_worldInverseTranspose;
            
        //     attribute vec4 a_position;
        //     attribute vec3 a_normal;
        //     attribute vec2 a_texcoord;
            
        //     varying vec4 v_position;
        //     varying vec2 v_texCoord;
        //     varying vec3 v_normal;
        //     varying vec3 v_surfaceToLight;
        //     varying vec3 v_surfaceToView;
            
        //     void main() {
        //         v_texCoord = a_texcoord;
        //         v_position = (u_worldViewProjection * a_position);
        //         v_normal = (u_worldInverseTranspose * vec4(a_normal, 0)).xyz;
        //         v_surfaceToLight = u_lightWorldPos - (u_world * a_position).xyz;
        //         v_surfaceToView = (u_viewInverse[3] - (u_world * a_position)).xyz;
        //         gl_Position = v_position;
        //     }
        // `;

        // this.fsSource = `
        //     precision mediump float;
    
        //     varying vec4 v_position;
        //     varying vec2 v_texCoord;
        //     varying vec3 v_normal;
        //     varying vec3 v_surfaceToLight;
        //     varying vec3 v_surfaceToView;
            
        //     uniform vec4 u_lightColor;
        //     uniform vec4 u_ambient;
        //     uniform sampler2D u_diffuse;
        //     uniform vec4 u_specular;
        //     uniform float u_shininess;
        //     uniform float u_specularFactor;
            
        //     vec4 lit(float l ,float h, float m) {
        //     return vec4(1.0,
        //                 max(l, 0.0),
        //                 (l > 0.0) ? pow(max(0.0, h), m) : 0.0,
        //                 1.0);
        //     }
            
        //     void main() {
        //         vec4 diffuseColor = texture2D(u_diffuse, v_texCoord);
        //         vec3 a_normal = normalize(v_normal);
        //         vec3 surfaceToLight = normalize(v_surfaceToLight);
        //         vec3 surfaceToView = normalize(v_surfaceToView);
        //         vec3 halfVector = normalize(surfaceToLight + surfaceToView);
        //         vec4 litR = lit(dot(a_normal, surfaceToLight),
        //                             dot(a_normal, halfVector), u_shininess);
        //         vec4 outColor = vec4((
        //         u_lightColor * (diffuseColor * litR.y + diffuseColor * u_ambient +
        //                         u_specular * litR.z * u_specularFactor)).rgb,
        //             diffuseColor.a);
        //         gl_FragColor = outColor;
        //     }
        // `;
        
        this.programInfo = WebGLUtil.createProgramInfo(Render.GL, this.vsSource, this.fsSource);
        this.shaderProgram = this.programInfo.program;
    }

    protected initBuffers():void{
        const gl = Render.GL;
		gl.enable(gl.DEPTH_TEST);
    }

    protected predraw():void{

    }

    /**
     * @Author: Snow
     * @description: 渲染
     * @param {any} param
     * @return {*}
     */    
    protected draw(param?:any):void{

    }

    public render(ts?:number):void{
        this.ts = ts;
        this.predraw();
        this.draw();
    }
}